﻿#pragma once

#include "Graphics/MLibraryV2.h"
#include "Graphics/Frames.h"
#include "../Shared/Enums.h"
#include "../Controls/FixedListViewControl/FixedListView.h"
#include <string>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <cmath>
#include <stdexcept>
#include <any>
#include <functional>
#include <cstdint>
#include "exceptionhelper.h"
#include "../stringhelper.h"
#include "../tangible_filesystem.h"

using namespace Shared::Extensions;


namespace LibraryEditor
{
    class LMain : public System::Windows::Forms::Form
    {
    private:
//C# TO C++ CONVERTER WARNING: C++ has no equivalent to a 'readonly' collection which allows modification of internal state:
//ORIGINAL LINE: private readonly Dictionary<int, int> _indexList = new Dictionary<int, int>();
        std::unordered_map<int, int> _indexList = std::unordered_map<int, int>();
        MLibraryV2 *_library;
        MLibraryV2::MImage *_selectedImage, *_exportImage;
        Image *_originalImage;

    protected:
        bool ImageTabActive = true;
        bool FrameTabActive = false;

//C# TO C++ CONVERTER NOTE: The following .NET DllImport attribute was converted using the Microsoft-specific __declspec(dllimport):
//[DllImport("user32.dll")]
    private:
        __declspec(dllimport) static int SendMessage(std::intptr_t hWnd, int msg, int wParam, int lParam);

    public:
        virtual ~LMain()
        {
            delete _library;
            delete _selectedImage;
            delete _exportImage;
            delete _originalImage;
            delete _drawFrame;
            delete components;
            delete MainMenu;
            delete fileToolStripMenuItem;
            delete newToolStripMenuItem;
            delete openToolStripMenuItem;
            delete toolStripMenuItem1;
            delete saveToolStripMenuItem;
            delete saveAsToolStripMenuItem;
            delete toolStripMenuItem2;
            delete closeToolStripMenuItem;
            delete splitContainer1;
            delete splitContainer2;
            delete ImageList;
            delete AddButton;
            delete HeightLabel;
            delete label6;
            delete WidthLabel;
            delete label1;
            delete OpenLibraryDialog;
            delete SaveLibraryDialog;
            delete ImportImageDialog;
            delete DeleteButton;
            delete OpenWeMadeDialog;
            delete functionsToolStripMenuItem;
            delete convertToolStripMenuItem;
            delete copyToToolStripMenuItem;
            delete removeBlanksToolStripMenuItem;
            delete countBlanksToolStripMenuItem;
            delete OffSetYTextBox;
            delete OffSetXTextBox;
            delete label10;
            delete label8;
            delete InsertImageButton;
            delete safeToolStripMenuItem;
            delete ExportButton;
            delete toolTip;
            delete ZoomTrackBar;
            delete ImageBox;
            delete panel;
            delete statusStrip;
            delete toolStripStatusLabel;
            delete toolStripProgressBar;
            delete pictureBox;
            delete skinToolStripMenuItem;
            delete buttonReplace;
            delete buttonSkipPrevious;
            delete buttonSkipNext;
            delete checkBoxQuality;
            delete checkBoxPreventAntiAliasing;
            delete nudJump;
            delete tabControl;
            delete tabImages;
            delete PreviewListView;
            delete tabFrames;
            delete frameGridView;
            delete populateFramesToolStripMenuItem;
            delete defaultMonsterFramesToolStripMenuItem;
            delete defaultPlayerFramesToolStripMenuItem;
            delete FolderLibraryDialog;
            delete autofillFromCodeToolStripMenuItem;
            delete FrameAction;
            delete FrameStart;
            delete FrameCount;
            delete FrameSkip;
            delete FrameInterval;
            delete FrameEffectStart;
            delete FrameEffectCount;
            delete FrameEffectSkip;
            delete FrameEffectInterval;
            delete FrameReverse;
            delete FrameBlend;
            delete defaultNPCFramesToolStripMenuItem;
            delete FrameAnimTimer;
        }

        LMain();

    private:
        void Form1_DragDrop(std::any sender, DragEventArgs *e);

        void Form1_DragEnter(std::any sender, DragEventArgs *e);

        void ClearInterface();

        void PreviewListView_SelectedIndexChanged(std::any sender, EventArgs *e);

        void PreviewListView_RetrieveVirtualItem(std::any sender, RetrieveVirtualItemEventArgs *e);

        void AddButton_Click(std::any sender, EventArgs *e);

        void newToolStripMenuItem_Click(std::any sender, EventArgs *e);

        void openToolStripMenuItem_Click(std::any sender, EventArgs *e);

        void OpenLibrary(const std::string &filename);

        void saveToolStripMenuItem_Click(std::any sender, EventArgs *e);

        void saveAsToolStripMenuItem_Click(std::any sender, EventArgs *e);

        void closeToolStripMenuItem_Click(std::any sender, EventArgs *e);

        void DeleteButton_Click(std::any sender, EventArgs *e);

        void convertToolStripMenuItem_Click(std::any sender, EventArgs *e);

        void copyToToolStripMenuItem_Click(std::any sender, EventArgs *e);

        void removeBlanksToolStripMenuItem_Click(std::any sender, EventArgs *e);

        void countBlanksToolStripMenuItem_Click(std::any sender, EventArgs *e);

        void OffSetXTextBox_TextChanged(std::any sender, EventArgs *e);

        void OffSetYTextBox_TextChanged(std::any sender, EventArgs *e);

        void InsertImageButton_Click(std::any sender, EventArgs *e);

        void safeToolStripMenuItem_Click(std::any sender, EventArgs *e);

        static constexpr int HowDeepToScan = 6;

    public:
        static void ProcessDir(const std::string &sourceDir, int recursionLvl, const std::string &outputDir);

        // Export a single image.
    private:
        void ExportButton_Click(std::any sender, EventArgs *e);

        // Don't let the splitter go out of sight on resizing.
        void LMain_Resize(std::any sender, EventArgs *e);

        // Resize the image(Zoom).
        Image *ImageBoxZoom(Image *image, Size *size);

        // Zoom in and out.
        void ZoomTrackBar_Scroll(std::any sender, EventArgs *e);

        // Swap the image panel background colour Black/White.
        void pictureBox_Click(std::any sender, EventArgs *e);

        void PreviewListView_VirtualItemsSelectionRangeChanged(std::any sender, ListViewVirtualItemsSelectionRangeChangedEventArgs *e);

        void buttonReplace_Click(std::any sender, EventArgs *e);

        void previousImageToolStripMenuItem_Click(std::any sender, EventArgs *e);

        void nextImageToolStripMenuItem_Click(std::any sender, EventArgs *e);

        // Move Left and Right through images.
    protected:
        bool ProcessCmdKey(Message *&msg, Keys *keyData) override;

    private:
        void buttonSkipNext_Click(std::any sender, EventArgs *e);

        void buttonSkipPrevious_Click(std::any sender, EventArgs *e);

        void checkBoxQuality_CheckedChanged(std::any sender, EventArgs *e);

        void checkBoxPreventAntiAliasing_CheckedChanged(std::any sender, EventArgs *e);

        void nudJump_ValueChanged(std::any sender, EventArgs *e);

        void nudJump_KeyDown(std::any sender, KeyEventArgs *e);

        #pragma region Frames

        void defaultMonsterFramesToolStripMenuItem_Click(std::any sender, EventArgs *e);

        void defaultNPCFramesToolStripMenuItem_Click(std::any sender, EventArgs *e);

        void defaultPlayerFramesToolStripMenuItem_Click(std::any sender, EventArgs *e);

        void tabControl_SelectedIndexChanged(std::any sender, EventArgs *e);

        void autofillNpcFramesToolStripMenuItem_Click(std::any sender, EventArgs *e);

        void frameGridView_CellValidating(std::any sender, DataGridViewCellValidatingEventArgs *e);

        void frameGridView_DefaultValuesNeeded(std::any sender, DataGridViewRowEventArgs *e);


        void UpdateFrameGridView();

        void UpdateFrameGridData();

        void frameGridView_RowEnter(std::any sender, DataGridViewCellEventArgs *e);

        Frame *_drawFrame;
        int _currentFrame = 0;
        MirDirection _currentDirection = static_cast<MirDirection>(0);

        void FrameAnimTimer_Tick(std::any sender, EventArgs *e);

        /// <summary>
        /// List of monsters and matching frames
        /// Method MUST be edited before use. The existing code is only here as an example.
        /// READ THE COMMENTS WITHIN THIS METHOD BEFORE USE
        /// </summary>
        /// <param name="image"></param>
        /// <returns></returns>
        FrameSet *GetFrameSetByImage(Monster image);
        #pragma endregion


        /// <summary>
        /// Required designer variable.
        /// </summary>
        System::ComponentModel::IContainer *components = nullptr;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected:
        void Dispose(bool disposing) override;

        #pragma region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
    private:
        void InitializeComponent();

        #pragma endregion

        System::Windows::Forms::MenuStrip *MainMenu;
        System::Windows::Forms::ToolStripMenuItem *fileToolStripMenuItem;
        System::Windows::Forms::ToolStripMenuItem *newToolStripMenuItem;
        System::Windows::Forms::ToolStripMenuItem *openToolStripMenuItem;
        System::Windows::Forms::ToolStripSeparator *toolStripMenuItem1;
        System::Windows::Forms::ToolStripMenuItem *saveToolStripMenuItem;
        System::Windows::Forms::ToolStripMenuItem *saveAsToolStripMenuItem;
        System::Windows::Forms::ToolStripSeparator *toolStripMenuItem2;
        System::Windows::Forms::ToolStripMenuItem *closeToolStripMenuItem;
        System::Windows::Forms::SplitContainer *splitContainer1;
        System::Windows::Forms::SplitContainer *splitContainer2;

        System::Windows::Forms::ImageList *ImageList;
        System::Windows::Forms::Button *AddButton;
        System::Windows::Forms::Label *HeightLabel;
        System::Windows::Forms::Label *label6;
        System::Windows::Forms::Label *WidthLabel;
        System::Windows::Forms::Label *label1;
        System::Windows::Forms::OpenFileDialog *OpenLibraryDialog;
        System::Windows::Forms::SaveFileDialog *SaveLibraryDialog;
        System::Windows::Forms::OpenFileDialog *ImportImageDialog;
        System::Windows::Forms::Button *DeleteButton;
        System::Windows::Forms::OpenFileDialog *OpenWeMadeDialog;
        System::Windows::Forms::ToolStripMenuItem *functionsToolStripMenuItem;
        System::Windows::Forms::ToolStripMenuItem *convertToolStripMenuItem;
        System::Windows::Forms::ToolStripMenuItem *copyToToolStripMenuItem;
        System::Windows::Forms::ToolStripMenuItem *removeBlanksToolStripMenuItem;
        System::Windows::Forms::ToolStripMenuItem *countBlanksToolStripMenuItem;
        System::Windows::Forms::TextBox *OffSetYTextBox;
        System::Windows::Forms::TextBox *OffSetXTextBox;
        System::Windows::Forms::Label *label10;
        System::Windows::Forms::Label *label8;
        System::Windows::Forms::Button *InsertImageButton;
        System::Windows::Forms::ToolStripMenuItem *safeToolStripMenuItem;
        System::Windows::Forms::Button *ExportButton;
        System::Windows::Forms::ToolTip *toolTip;
        System::Windows::Forms::TrackBar *ZoomTrackBar;
        System::Windows::Forms::PictureBox *ImageBox;
        System::Windows::Forms::Panel *panel;
        System::Windows::Forms::StatusStrip *statusStrip;
        System::Windows::Forms::ToolStripStatusLabel *toolStripStatusLabel;
        System::Windows::Forms::ToolStripProgressBar *toolStripProgressBar;
        System::Windows::Forms::PictureBox *pictureBox;
        System::Windows::Forms::ToolStripMenuItem *skinToolStripMenuItem;
        System::Windows::Forms::Button *buttonReplace;
        System::Windows::Forms::Button *buttonSkipPrevious;
        System::Windows::Forms::Button *buttonSkipNext;
        System::Windows::Forms::CheckBox *checkBoxQuality;
        System::Windows::Forms::CheckBox *checkBoxPreventAntiAliasing;
        System::Windows::Forms::NumericUpDown *nudJump;
        System::Windows::Forms::TabControl *tabControl;
        System::Windows::Forms::TabPage *tabImages;
        CustomFormControl::FixedListView *PreviewListView;
        System::Windows::Forms::TabPage *tabFrames;
        System::Windows::Forms::DataGridView *frameGridView;
        System::Windows::Forms::ToolStripMenuItem *populateFramesToolStripMenuItem;
        System::Windows::Forms::ToolStripMenuItem *defaultMonsterFramesToolStripMenuItem;
        System::Windows::Forms::ToolStripMenuItem *defaultPlayerFramesToolStripMenuItem;
        System::Windows::Forms::FolderBrowserDialog *FolderLibraryDialog;
        System::Windows::Forms::ToolStripMenuItem *autofillFromCodeToolStripMenuItem;
        System::Windows::Forms::DataGridViewComboBoxColumn *FrameAction;
        System::Windows::Forms::DataGridViewTextBoxColumn *FrameStart;
        System::Windows::Forms::DataGridViewTextBoxColumn *FrameCount;
        System::Windows::Forms::DataGridViewTextBoxColumn *FrameSkip;
        System::Windows::Forms::DataGridViewTextBoxColumn *FrameInterval;
        System::Windows::Forms::DataGridViewTextBoxColumn *FrameEffectStart;
        System::Windows::Forms::DataGridViewTextBoxColumn *FrameEffectCount;
        System::Windows::Forms::DataGridViewTextBoxColumn *FrameEffectSkip;
        System::Windows::Forms::DataGridViewTextBoxColumn *FrameEffectInterval;
        System::Windows::Forms::DataGridViewCheckBoxColumn *FrameReverse;
        System::Windows::Forms::DataGridViewCheckBoxColumn *FrameBlend;
        System::Windows::Forms::ToolStripMenuItem *defaultNPCFramesToolStripMenuItem;
        System::Windows::Forms::Timer *FrameAnimTimer;
    };
}
